<?php

namespace Theatre\Server;

class Ticket extends \Theatre\Controller {
	/**
	 * Issue a booking
	 */
	function booking() {
		$this->view('JSON');

		$requestValid = $this->APIRequestIsValid($this->params);

		if ($requestValid['status'] == 'error') {
			$this->set($requestValid);

			return;
		}

		$partner = $requestValid['partner'];

		if (empty($this->params['representation_id']) || !is_numeric($this->params['representation_id'])) {
			$this->set(array(
				'status' => 'error',
				'message' => 'No representation Id provided'
			));

			return;
		}

		if (empty($this->params['user_id']) || !is_numeric($this->params['user_id'])) {
			$this->set(array(
				'status' => 'error',
				'message' => 'No user Id provided'
			));

			return;
		}


		if (!empty($this->params['request_seats']) && $this->params['request_seats'] == '1') {
			if (empty($this->params['show_id']) || !is_numeric($this->params['show_id'])) {
				$this->set(array(
					'status' => 'error',
					'message' => 'No Show Id provided'
				));

				return;
			}

			if (empty($this->params['hall_id']) || !is_numeric($this->params['hall_id'])) {
				$this->set(array(
					'status' => 'error',
					'message' => 'No hall Id provided'
				));

				return;
			}

			if (empty($this->params['seat_no']) || !is_numeric($this->params['seat_no']) || $this->params['seat_no'] <= 0) {
				$this->set(array(
					'status' => 'error',
					'message' => 'No seats provided'
				));

				return;
			}

			$this->model('PostGreSQL')->dbQuery('BEGIN WORK');
			$this->model('PostGreSQL')->dbQuery('LOCK TABLE booking IN ACCESS EXCLUSIVE MODE');
			$this->model('PostGreSQL')->dbQuery('LOCK TABLE booking_ticket IN ACCESS EXCLUSIVE MODE');

			// delete any uncompleted bookings since we're requesting new one
			$this->model('PostGreSQL')->dbRun(
				'deleteUnconfirmedBooking($1, $2, $3)',
				$this->params['user_id'],
				$partner->id,
				$this->params['representation_id']
			);

			// return the empty seats
			// ask for table lock
			$bookedSeatsResult = $this->model('PostGreSQL')->dbRun(
				'getBookings($1, $2, $3, $4, $5)',
				$this->params['representation_id'],
				$partner->id,
				$this->params['show_id'],
				$this->params['user_id'],
				$this->params['hall_id']
			);

			$theatreHall = $this->model('PostGreSQL')->dbRun('getTheatreHallById($1)', $this->params['hall_id']);
			$allSeats = range(1, $theatreHall->seats);
			$bookedSeats = array();

			if (is_object($bookedSeatsResult)) {
				$bookedSeats[] = $bookedSeatsResult->seat_no;
			}
			else {
				while ($booking = $this->model('PostGreSQL')->dbFetchObject($bookedSeatsResult)) {
					$bookedSeats[$booking->seat_no] = $booking->seat_no;
				}
			}

			$suggestedSeats = array();
			$freeSeats = array_diff($allSeats, $bookedSeats);
			$freeSeats = array_values($freeSeats);

			if (count($freeSeats) < $this->params['seat_no']) {
				$suggestedSeats = $freeSeats;
			}
			else {
				$freeSeatsNoExceptions = $freeSeats;
				// remove the previous choosed seats, we ditched them, we don't like them
				if (!empty($this->params['seat_exception']) && is_array($this->params['seat_exception'])) {
					$freeSeatsNoExceptions = array_diff($freeSeats, $this->params['seat_exception']);
					$freeSeatsNoExceptions = array_values($freeSeatsNoExceptions);
				}

				// the remaining seats are less than requested
				if (count($freeSeatsNoExceptions) < $this->params['seat_no']) {
					for ($i = 0; $i < $this->params['seat_no']; $i++) {
						$suggestedSeats[] = $freeSeats[$i];
					}
				}
				else {
					for ($i = 0; $i < $this->params['seat_no']; $i++) {
						$suggestedSeats[] = $freeSeatsNoExceptions[$i];
					}
				}
			}

			$arrayToString = implode(',', $suggestedSeats);

			// insert the suggested seats
			$this->model('PostGreSQL')->dbRun(
				'addUnconfirmedBooking($1, $2, $3, $4, $5, $6, $7)',
				$this->params['seat_no'],
				$partner->id,
				$this->params['user_id'],
				date('Y-m-d H:i:s'),
				$this->params['representation_id'],
				$this->params['show_id'],
				$arrayToString
			);


			// release the lock
			$this->model('PostGreSQL')->dbQuery('COMMIT WORK');

			$this->set(array(
				'seats'  => $suggestedSeats,
				'status' => 'success'
			));

			return;
		}
		else {
			// seats confirmed, update the last booking
			$this->model('PostGreSQL')->dbRun(
				"confirmBooking($1, $2, $3, $4)",
				$this->params['name'],
				$this->params['user_id'],
				$partner->id,
				$this->params['representation_id']
			);

			$this->set(array(
				'status' => 'success'
			));
		}
	}
}
